//最大生成树

#include <algorithm>
#include <iostream>
#include <map>
#include <numeric> // For std::iota (though not strictly needed for this DSU)
#include <set>
#include <vector>

using std::cin;
using std::cout;
using std::map;
using std::max;
using std::min;
using std::pair;
using std::set;

#define lld long long
#define ENDL \n
// 定义边的结构体
struct Edge {
  int u, v, weight;
};

bool cmp(const Edge &a, const Edge &b) { return a.weight > b.weight; }

struct DSU {
  std::vector<int> parent;
  std::vector<int> sz;
  DSU(int n) {
    parent.resize(n + 1);
    sz.resize(n + 1);
    for (int i = 0; i < parent.size(); ++i)
      parent[i] = i;
  }
  int find(int i) {
    if (parent[i] == i)
      return i;
    else {
      while (i != parent[i]) {
        i = parent[i];
      }
      return i;
    }
  }
  bool unite(int u, int v) {
    int root_u = find(u);
    int root_v = find(v);
    if (root_u != root_v) {
      parent[root_v] = root_u;
      return true;
    }
    return false;
  }
};
void solve() {
  int n, m;
  std::cin >> n >> m;

  std::vector<Edge> edges;
  while (m--) {
    int u, v, val;
    cin >> u >> v >> val;
    edges.push_back({u, v, val});
  }
  std::sort(edges.begin(), edges.end(), cmp);
  DSU dsu(n);
  std::vector<Edge> mst;
  for (auto x : edges) {
    if (dsu.unite(x.u, x.v)) {
      mst.push_back({x.u, x.v, x.weight});
      if (mst.size() == n - 1) {
        break;
      }
    }
  }
  if (mst.size() == n - 1) {
    lld tot = 0;
    for (auto x : mst)
      tot += x.weight;
    std::cout << tot << std::endl;
  }
}
int main() {

  std::ios_base::sync_with_stdio(false);
  std::cin.tie(NULL);

  int T = 1;
  std::cin >> T;

  while (T--) {
    solve();
  }
  return 0;
}